from django.db import models
from terminal.models import Terminal


class QuestionAnswer(models.Model):
    """提问下发与提问应答

    记录提问下发与终端传回的提问回答结果 0x8302 0x0302
    """
    StatusChoice = (
        ('INIT', '等待下发'),
        ('QUESTION', '已下发'),
        ('ANSWERED', '已回答'),
    )
    # 808
    flag = models.SmallIntegerField(
        default=0b0000_1000,
        verbose_name="""
        提问下发标志位定义
        0x00-0xFF
        位      标志
        --     ----
        0       1：紧急
        1       保留
        2       保留
        3       1：终端TTS 播读
        4       1：广告屏显示
        5-7     保留
        """,
    )
    question = models.CharField(max_length=120, verbose_name='问题内容')
    # TODO: 待定，JT808文档中是`答案列表`，C#接口中是`AnswerId`, `AnswerContentLength`, `AnswerContent`三项
    candidate_answers = models.CharField(max_length=200, blank=True, null=True, verbose_name='候选答案列表')
    # 808 应答
    answer = models.CharField(max_length=120, blank=True, null=True, verbose_name='回答内容')
    answer_time = models.DateTimeField(blank=True, null=True, verbose_name='回答时间')
    # 自定义
    terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE, db_index=True, verbose_name='终端')
    status = models.CharField(max_length=15, choices=StatusChoice, default=StatusChoice[0][0], verbose_name='状态')
    created_time = models.DateTimeField(auto_now_add=True, editable=False)
    modified_on = models.DateTimeField(auto_now=True)

    @property
    def question_length(self):
        """问题内容长度
        0x00-0xFF
        经过GBK编码以后的内容长度
        """
        l = len(self.question.encode('gbk'))
        if 0x00 <= l <= 0xFF:
            return l
        else:
            raise ValueError('question content too long!')

    @property
    def answer_length(self):
        """答案内容长度
        0x00-0xFF
        经过GBK编码以后的内容长度
        """
        l = len(self.answer.encode('gbk'))
        if 0x00 <= l <= 0xFF:
            return l
        else:
            raise ValueError('answer content too long!')

    class Meta:
        db_table = 'question_answer'


class RSAPublicKey(models.Model):
    """终端公钥存储
    """
    # 808
    e = models.IntegerField()
    n = models.CharField(max_length=128)
    # 自定义
    terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE, db_index=True, verbose_name='终端')

    class Meta:
        db_table = 'rsa_public_key'


class Text(models.Model):
    """文本信息
    文本信息下发，0x8300
    """
    # 808
    flag = models.SmallIntegerField(
        default=0b0000_0000,
        verbose_name="""
        0x00-0xFF
        位      标志
        --      ----
        0       1：紧急
        1       保留
        2       1：终端显示器显示
        3       1：终端TTS 播读
        4       1：广告屏显示
        5       0：中心导航信息，1：CAN 故障码信息
        6-7     保留
        """,
    )
    content = models.TextField(verbose_name='最长为1024字节，经GBK编码')
    # 自定义
    terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE, db_index=True, verbose_name='终端')

    class Meta:
        db_table = 'text'


class UpgradePackageDelivery(models.Model):
    """下发终端升级包
    0x8108
    """
    CategoryChoice = (
        (0, '终端'),
        (12, '道路运输证IC卡读卡器'),
        (52, '北斗卫星定位模块'),
    )
    # 808
    category = models.SmallIntegerField(
        choices=CategoryChoice,
        default=CategoryChoice[0][0],
        verbose_name="""
        升级类型 0x00-0xFF
        (0, '终端'),
        (12, '道路运输证IC卡读卡器'),
        (52, '北斗卫星定位模块'),
        """,
    )
    name = models.CharField(max_length=30)
    manufacturer_id = models.CharField(max_length=15, verbose_name='制造商ID')
    version = models.CharField(max_length=50, verbose_name='版本号')
    package_length = models.IntegerField(verbose_name="""
        升级数据包长度单位为BYTE
        808协议中此字段类型为DWORD，故最长为0xFFFF
        升级包最大为64KB
        """)
    # 自定义
    package_url = models.CharField(max_length=200, verbose_name='升级包的URL地址')
    terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE, db_index=True, verbose_name='终端')

    @property
    def version_length(self):
        """版本号长度
        808协议中最长为0xFF，这里限制50
        """
        return len(self.version)

    class Meta:
        db_table = 'upgrade_package_delivery'


class UpgradePackageResult(models.Model):
    """终端升级结果通知
    0x0108
    """
    CategoryChoice = (
        (0, '终端'),
        (12, '道路运输证IC卡读卡器'),
        (52, '北斗卫星定位模块'),
    )
    ResultChoice = (
        (0, '成功'),
        (1, '失败'),
        (2, '取消')
    )

    terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE, db_index=True, verbose_name='终端')
    package = models.ForeignKey(UpgradePackageDelivery, on_delete=models.CASCADE, db_index=True, verbose_name='升级包')
    category = models.IntegerField(choices=CategoryChoice, default=CategoryChoice[0][0])
    result = models.IntegerField(choices=ResultChoice, default=ResultChoice[0][0], verbose_name='升级结果')

    class Meta:
        db_table = 'upgrade_package_result'
